package deng.java.examples;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class MainHelper {

	public static String inspect(Object object) {
		return inspect(object, false);
	}
	
	public static String inspect(Object object, boolean multilines) {
		String ret;
		if (multilines)
			ret = ToStringBuilder.reflectionToString(object, ToStringStyle.MULTI_LINE_STYLE);
		else
			ret = ToStringBuilder.reflectionToString(object, ToStringStyle.DEFAULT_STYLE);
		return ret;
	}
	
	public static String inspectClass(Class<?> cls) {
		List<?> superClasses = ClassUtils.getAllSuperclasses(cls);
		List<?> superInterfaces = ClassUtils.getAllInterfaces(cls);
		String ret = "{superClasses=" + superClasses + ", superInterfaces=" + superInterfaces + "}";
		return ret;
	}
	
	public static void print(Object object) {
		System.out.print(object);
	}
	
	public static void println(Object object) {
		System.out.println(object);
	}
	
	public static void p(Object object) {
		println(object);
	}

	public static <T> List<T> list(T ... objects) {
		List<T> ls = new ArrayList<T>();
		for (T obj : objects) {
			ls.add(obj);
		}
		return ls;
	}
	
	public static Map<String, Object> map(Object ... objects) {
		assert(objects.length % 2 == 0);
		Map<String, Object> map = new HashMap<String, Object>(objects.length / 2);
		int i = 0;
		while (i < objects.length) {
			map.put((String)objects[i++], objects[i++]);
		}
		return map;
	}

	public static <A, B> Map<A, B> mapFromTuple2(Tuple2<A, B> ... pairs) {
		Map<A, B> map = new HashMap<A, B>();
		for (Tuple2<A, B> pair : pairs) {
			map.put(pair._1(), pair._2());
		}
		return map;
	}
	
	public static <A, B> Tuple2<A, B> pair(A a, B b) {
		return new Tuple2<A, B>(a, b);
	}

	public static class Tuple2<A, B> {
		private A a;
		private B b;
		public Tuple2(A a, B b) {
			this.a = a;
			this.b = b;
		}
		public A _1(){ return a; }
		public B _2(){ return b; }
	}
	
}
